{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {
    "ein.tags": "worksheet-0",
    "slideshow": {
     "slide_type": "-"
    }
   },
   "source": [
    "\n",
    "介绍numpy/scipy库的基本用法.\n",
    "\n",
    "<!-- TEASER_END -->"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {
    "autoscroll": false,
    "collapsed": false,
    "ein.hycell": false,
    "ein.tags": "worksheet-0",
    "slideshow": {
     "slide_type": "-"
    }
   },
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "import scipy\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {
    "autoscroll": false,
    "collapsed": false,
    "ein.hycell": false,
    "ein.tags": "worksheet-0",
    "slideshow": {
     "slide_type": "-"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[[ 0  1  2  3  4]\n",
      " [ 5  6  7  8  9]\n",
      " [10 11 12 13 14]]\n"
     ]
    }
   ],
   "source": [
    "\n",
    "# arange 函数, 生成多维数组\n",
    "a = np.arange(15).reshape(3, 5)\n",
    "print(a)\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {
    "autoscroll": false,
    "collapsed": false,
    "ein.hycell": false,
    "ein.tags": "worksheet-0",
    "slideshow": {
     "slide_type": "-"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "每个元素内存大小(单位是byte, int64 是64bit, 64/8=8byte): 8\n",
      "纬度(3行5列，表示为二维数组，所以纬度是2): 2\n",
      "元素类型 int64\n",
      "总元素大小 15\n"
     ]
    }
   ],
   "source": [
    "print(\"每个元素内存大小(单位是byte, int64 是64bit, 64/8=8byte):\", a.itemsize)\n",
    "print(\"纬度(3行5列，表示为二维数组，所以纬度是2):\", a.ndim)\n",
    "print(\"元素类型\", a.dtype)\n",
    "print(\"总元素大小\", a.size)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 37,
   "metadata": {
    "autoscroll": false,
    "collapsed": false,
    "ein.hycell": false,
    "ein.tags": "worksheet-0",
    "slideshow": {
     "slide_type": "-"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "一维数组: [1 2 3 4] 1\n",
      "二维数组：  [[1.5 2.  3. ]\n",
      " [4.  5.  6. ]] 2\n",
      "指定数据类型为复数: [[1.+0.j 2.+0.j]\n",
      " [3.+0.j 4.+0.j]]\n",
      "生成值全部是0的数组:  [[0. 0. 0. 0.]\n",
      " [0. 0. 0. 0.]\n",
      " [0. 0. 0. 0.]]\n",
      "生成值全部是1的数组:  [[1. 1. 1. 1.]\n",
      " [1. 1. 1. 1.]\n",
      " [1. 1. 1. 1.]]\n",
      "生成未初始化值的数组:  [[1.5 2.  3. ]\n",
      " [4.  5.  6. ]]\n",
      "生成一定步长的连续数组: [10 15 20 25 30 35 40 45 50 55 60 65 70 75 80 85 90 95]\n",
      "更改数组纬度: [[   0    1    2 ...   97   98   99]\n",
      " [ 100  101  102 ...  197  198  199]\n",
      " [ 200  201  202 ...  297  298  299]\n",
      " ...\n",
      " [9700 9701 9702 ... 9797 9798 9799]\n",
      " [9800 9801 9802 ... 9897 9898 9899]\n",
      " [9900 9901 9902 ... 9997 9998 9999]]\n"
     ]
    }
   ],
   "source": [
    "# 可以直接使用python 本身的list创建数组\n",
    "\n",
    "a = np.array([1, 2, 3, 4])\n",
    "\n",
    "print(\"一维数组:\", a, a.ndim)\n",
    "\n",
    "b = np.array([(1.5,2,3), (4,5,6)])\n",
    "print(\"二维数组： \", b, b.ndim)\n",
    "\n",
    "# 指定数据类型\n",
    "c = np.array( [ [1,2], [3,4] ], dtype=complex )\n",
    "print(\"指定数据类型为复数:\", c)\n",
    "\n",
    "\n",
    "# 还有一些快速生成一定规则数组的方法\n",
    "print(\"生成值全部是0的数组: \", np.zeros((3, 4)))\n",
    "print(\"生成值全部是1的数组: \", np.ones((3, 4)))\n",
    "print(\"生成未初始化值的数组: \", np.empty((2, 3)))\n",
    "\n",
    "print(\"生成一定步长的连续数组:\", np.arange(10, 100, 5))\n",
    "\n",
    "print( \"更改数组纬度:\", np.arange(10000).reshape(100,100))\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {
    "autoscroll": false,
    "collapsed": false,
    "ein.hycell": false,
    "ein.tags": "worksheet-0",
    "slideshow": {
     "slide_type": "-"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "a-b= [20 29 38 47]\n",
      "a*2= [ 40  60  80 100]\n",
      "b**2 =  [0 1 4 9]\n",
      "sin(a) =  [ 0.91294525 -0.98803162  0.74511316 -0.26237485]\n",
      "cos(a) =  [ 0.40808206  0.15425145 -0.66693806  0.96496603]\n",
      "a < 35 =  [ True  True False False]\n"
     ]
    }
   ],
   "source": [
    "# 加减运算\n",
    "a = np.array( [20,30,40,50] )\n",
    "b = np.arange(4)\n",
    "\n",
    "print(\"a-b=\", a-b)\n",
    "print(\"a*2=\", a*2)\n",
    "\n",
    "print(\"b**2 = \", b**2)\n",
    "print(\"sin(a) = \", np.sin(a))\n",
    "print(\"cos(a) = \", np.cos(a))\n",
    "\n",
    "print(\"a < 35 = \", a<35)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 50,
   "metadata": {
    "autoscroll": false,
    "collapsed": false,
    "ein.hycell": false,
    "ein.tags": "worksheet-0",
    "slideshow": {
     "slide_type": "-"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "A:  [[0 1]\n",
      " [2 3]]\n",
      "B:  [[4 5]\n",
      " [6 7]]\n"
     ]
    }
   ],
   "source": [
    "A = np.arange(0, 4, 1).reshape(2, 2)\n",
    "B = np.arange(4, 8, 1).reshape(2, 2)\n",
    "\n",
    "print(\"A: \", A)\n",
    "print(\"B: \", B)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {
    "autoscroll": false,
    "collapsed": false,
    "ein.hycell": false,
    "ein.tags": "worksheet-0",
    "slideshow": {
     "slide_type": "-"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "a+b= [1.         2.57079633 4.14159265]\n"
     ]
    }
   ],
   "source": [
    "a = np.ones(3, dtype=np.int32)\n",
    "b = np.linspace(0, np.pi, 3)\n",
    "\n",
    "print(\"a+b=\", a+b)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {
    "autoscroll": false,
    "collapsed": false,
    "ein.hycell": false,
    "ein.tags": "worksheet-0",
    "slideshow": {
     "slide_type": "-"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "a= [[0 1 2]\n",
      " [3 4 5]]\n",
      "a.sum= 15\n",
      "a.min= 0\n",
      "a.max= 5\n",
      "a.sum of each column [3 5 7]\n",
      "a.sum of each row [ 3 12]\n",
      "a cumulative sum of cumulative each column [[0 1 2]\n",
      " [3 5 7]]\n",
      "a cumulative sum of cumulative each row [[ 0  1  3]\n",
      " [ 3  7 12]]\n"
     ]
    }
   ],
   "source": [
    "\n",
    "a = np.arange(6).reshape(2,3)\n",
    "print(\"a=\", a)\n",
    "\n",
    "print(\"a.sum=\", a.sum())\n",
    "\n",
    "\n",
    "print(\"a.min=\", a.min())\n",
    "\n",
    "print(\"a.max=\", a.max())\n",
    "\n",
    "print(\"a.sum of each column\", a.sum(axis=0))\n",
    "print(\"a.sum of each row\", a.sum(axis=1))\n",
    "print(\"a cumulative sum of cumulative each column\", a.cumsum(axis=0))\n",
    "\n",
    "print(\"a cumulative sum of cumulative each row\", a.cumsum(axis=1))\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {
    "autoscroll": false,
    "collapsed": false,
    "ein.hycell": false,
    "ein.tags": "worksheet-0",
    "slideshow": {
     "slide_type": "-"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "B= [0 1 2]\n",
      "np.exp(B)= [1.         2.71828183 7.3890561 ]\n",
      "np.sqrt(B)= [0.         1.         1.41421356]\n"
     ]
    }
   ],
   "source": [
    "B = np.arange(3)\n",
    "print(\"B=\", B)\n",
    "\n",
    "print(\"np.exp(B)=\", np.exp(B))\n",
    "print(\"np.sqrt(B)=\", np.sqrt(B))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "metadata": {
    "autoscroll": false,
    "collapsed": false,
    "ein.hycell": false,
    "ein.tags": "worksheet-0",
    "slideshow": {
     "slide_type": "-"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "a= [  0   1   8  27  64 125 216 343 512 729]\n",
      "a[2]= 8\n",
      "a[2:5]= [ 8 27 64]\n",
      "a after a[:6:2] = -1000:  [-1000     1 -1000    27 -1000   125   216   343   512   729]\n",
      "a[ : :-1] =  [  729   512   343   216   125 -1000    27 -1000     1 -1000]\n"
     ]
    }
   ],
   "source": [
    "a = np.arange(10)**3\n",
    "print(\"a=\", a)\n",
    "print(\"a[2]=\", a[2])\n",
    "print(\"a[2:5]=\", a[2:5])\n",
    "\n",
    "a[:6:2] = -1000\n",
    "print(\"a after a[:6:2] = -1000: \", a)\n",
    "print(\"a[ : :-1] = \", a[ : :-1])\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 27,
   "metadata": {
    "autoscroll": false,
    "collapsed": false,
    "ein.hycell": false,
    "ein.tags": "worksheet-0",
    "slideshow": {
     "slide_type": "-"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "通过函数,输入行列坐标，生成二维数组: [[ 0  1  2  3]\n",
      " [10 11 12 13]\n",
      " [20 21 22 23]\n",
      " [30 31 32 33]\n",
      " [40 41 42 43]]\n",
      "b[2, 3]= 23\n",
      "b[0:5, 1]= [ 1 11 21 31 41]\n"
     ]
    }
   ],
   "source": [
    "def f(x,y):\n",
    "    return 10*x+y\n",
    "\n",
    "b = np.fromfunction(f,(5,4),dtype=int)\n",
    "print(\"通过函数,输入行列坐标，生成二维数组:\", b)\n",
    "\n",
    "print(\"b[2, 3]=\", b[2, 3])\n",
    "print(\"b[0:5, 1]=\", b[0:5, 1])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 35,
   "metadata": {
    "autoscroll": false,
    "collapsed": false,
    "ein.hycell": false,
    "ein.tags": "worksheet-0",
    "slideshow": {
     "slide_type": "-"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "c= [[[ 0  1  2]\n",
      "  [ 3  4  5]]\n",
      "\n",
      " [[ 6  7  8]\n",
      "  [ 9 10 11]]]\n",
      "c[1, ...]= [[ 6  7  8]\n",
      " [ 9 10 11]]\n",
      "c[..., 2]= [[ 2  5]\n",
      " [ 8 11]]\n",
      "c.flat= [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]\n"
     ]
    }
   ],
   "source": [
    "\n",
    "c = np.arange(12).reshape((2, 2,3))\n",
    "print(\"c=\",c)\n",
    "print('c[1, ...]=', c[1,...])\n",
    "print('c[..., 2]=', c[...,2])\n",
    "\n",
    "print('c.flat=', [e for e in c.flat])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 45,
   "metadata": {
    "autoscroll": false,
    "collapsed": false,
    "ein.hycell": false,
    "ein.tags": "worksheet-0",
    "slideshow": {
     "slide_type": "-"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "a= [[8. 4.]\n",
      " [6. 0.]]\n",
      "b= [[5. 8.]\n",
      " [9. 4.]]\n",
      "np.vstack((a,b)) [[8. 4.]\n",
      " [6. 0.]\n",
      " [5. 8.]\n",
      " [9. 4.]]\n",
      "np.hstack((a,b)) [[8. 4. 5. 8.]\n",
      " [6. 0. 9. 4.]]\n",
      "np.concatenate((a, b), axis=0)= [[8. 4.]\n",
      " [6. 0.]\n",
      " [5. 8.]\n",
      " [9. 4.]]\n"
     ]
    }
   ],
   "source": [
    "# 多维数组栈/拼接操作\n",
    "\n",
    "a = np.floor(10* np.random.random((2, 2)))\n",
    "b = np.floor(10* np.random.random((2, 2)))\n",
    "\n",
    "print(\"a=\", a)\n",
    "print(\"b=\", b)\n",
    "\n",
    "print(\"np.vstack((a,b))\", np.vstack((a,b)))\n",
    "print(\"np.hstack((a,b))\", np.hstack((a,b)))\n",
    "\n",
    "print(\"np.concatenate((a, b), axis=0)=\", np.concatenate((a, b), axis=0))\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 49,
   "metadata": {
    "autoscroll": false,
    "collapsed": false,
    "ein.hycell": false,
    "ein.tags": "worksheet-0",
    "slideshow": {
     "slide_type": "-"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "np.array_split(a, 4 , axis=1)= [array([[8., 8., 5.],\n",
      "       [4., 0., 9.],\n",
      "       [2., 6., 3.],\n",
      "       [0., 3., 0.]]), array([[3., 3., 1.],\n",
      "       [3., 9., 2.],\n",
      "       [6., 4., 4.],\n",
      "       [9., 3., 8.]]), array([[6., 4., 4.],\n",
      "       [5., 1., 6.],\n",
      "       [0., 4., 4.],\n",
      "       [0., 7., 6.]]), array([[8., 8., 3.],\n",
      "       [0., 8., 1.],\n",
      "       [6., 0., 5.],\n",
      "       [2., 9., 9.]])]\n"
     ]
    }
   ],
   "source": [
    "# spliting\n",
    "\n",
    "a = np.floor(10*np.random.random((4,12)))\n",
    "\n",
    "print(\"np.array_split(a, 4 , axis=1)=\", np.array_split(a, 4 , axis=1))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 64,
   "metadata": {
    "autoscroll": false,
    "collapsed": false,
    "ein.hycell": false,
    "ein.tags": "worksheet-0",
    "slideshow": {
     "slide_type": "-"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "a= [ 0  1  2  3  4  5  6  7  8  9 10 11]\n",
      "b is a= True\n",
      "c is a = False\n",
      "c.base is a = True\n",
      "c.flags.owndata =  False\n",
      "d is a = False\n",
      "d.base is a = True\n",
      "d.flags.owndata =  False\n",
      "a= [[ 0  1  2  3]\n",
      " [ 4  5  6  7]\n",
      " [ 8  9 10 11]]\n",
      "e is a =  False\n"
     ]
    }
   ],
   "source": [
    "# array copy\n",
    "\n",
    "a= np.arange(12)\n",
    "print(\"a=\", a)\n",
    "b = a\n",
    "b.shape = 3, 4\n",
    "\n",
    "print(\"b is a=\", b is a)\n",
    "\n",
    "c = a.view()\n",
    "\n",
    "print(\"c is a =\", c is a)\n",
    "print(\"c.base is a =\", c.base is a)\n",
    "\n",
    "print(\"c.flags.owndata = \", c.flags.owndata)\n",
    "\n",
    "d = a[:, 1:3]\n",
    "\n",
    "print(\"d is a =\", d is a)\n",
    "print(\"d.base is a =\", d.base is a)\n",
    "\n",
    "print(\"d.flags.owndata = \", d.flags.owndata)\n",
    "print(\"a=\", a)\n",
    "\n",
    "e = a.copy()\n",
    "print(\"e is a = \", e is a)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 67,
   "metadata": {
    "autoscroll": false,
    "collapsed": false,
    "ein.hycell": false,
    "ein.tags": "worksheet-0",
    "slideshow": {
     "slide_type": "-"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "a= [[ 0  1  2  3]\n",
      " [ 4  5  6  7]\n",
      " [ 8  9 10 11]]\n",
      "b= [[False False False False]\n",
      " [False  True  True  True]\n",
      " [ True  True  True  True]]\n",
      "a[b]= [ 5  6  7  8  9 10 11]\n",
      "after a[b] = 0, a =  [[0 1 2 3]\n",
      " [4 0 0 0]\n",
      " [0 0 0 0]]\n"
     ]
    }
   ],
   "source": [
    "# fancy indexing and index tricks\n",
    "\n",
    "a = np.arange(12).reshape(3,4)\n",
    "b = a > 4\n",
    "\n",
    "print(\"a=\", a)\n",
    "print(\"b=\", b)\n",
    "print(\"a[b]=\", a[b])\n",
    "\n",
    "a[b] = 0\n",
    "print(\"after a[b] = 0, a = \", a)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 101,
   "metadata": {
    "autoscroll": false,
    "collapsed": false,
    "ein.hycell": false,
    "ein.tags": "worksheet-0",
    "slideshow": {
     "slide_type": "-"
    }
   },
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "# 利用boolean类型的索引生成 Mandelbrot（曼德勃罗图像）\n",
    "import matplotlib.pyplot as plt\n",
    "def mandelbrot( h,w, maxit=20 ):\n",
    "    \"\"\"Returns an image of the Mandelbrot fractal of size (h,w).\"\"\"\n",
    "    y,x = np.ogrid[ -1.4:1.4:h*1j, -2:0.8:w*1j ]\n",
    "    c = x+y*1j\n",
    "    z=c\n",
    "    # print(id(z), id(c))\n",
    "    divtime = maxit + np.zeros(z.shape, dtype=int) \n",
    "    for i in range(maxit):\n",
    "        z = z**2 + c\n",
    "        diverge = z*np.conj(z) > 2**2 # who is diverging\n",
    "        div_now = diverge & (divtime==maxit) # who is diverging now\n",
    "        divtime[div_now] = i\n",
    "        z[diverge] = 2\n",
    "    return divtime\n",
    "plt.imshow(mandelbrot(800,800, 20))\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 105,
   "metadata": {
    "autoscroll": false,
    "collapsed": false,
    "ein.hycell": false,
    "ein.tags": "worksheet-0",
    "slideshow": {
     "slide_type": "-"
    }
   },
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "import matplotlib.pyplot as plt\n",
    "rng = np.random.RandomState(10)  # deterministic random data\n",
    "#print(rng.normal(size=1000))\n",
    "a = np.hstack((rng.normal(size=1000), rng.normal(loc=5, scale=2, size=1000)))\n",
    "\n",
    "plt.hist(a, bins='auto')  # arguments are passed to np.histogram\n",
    "plt.title(\"Histogram with 'auto' bins\")\n",
    "plt.show()"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "argv": [
    "/home/vincent/.pyenv/shims/python3",
    "-m",
    "ipykernel",
    "-f",
    "{connection_file}"
   ],
   "display_name": "Python3",
   "env": null,
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.8"
  },
  "name": "numpy_example.ipynb",
  "nbTranslate": {
   "displayLangs": [
    "*"
   ],
   "hotkey": "alt-t",
   "langInMainMenu": true,
   "sourceLang": "en",
   "targetLang": "fr",
   "useGoogleTranslate": true
  },
  "nikola": {
   "category": "",
   "date": "2018-05-22 16:58:15 UTC+08:00",
   "description": "",
   "link": "",
   "slug": "numpy_example",
   "tags": "",
   "title": "numpy_example",
   "type": "text"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
